package com.sk.rpcAssist.util;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * description：
 *
 * @author 孙文斌
 * @Date: 2021/2/3 14:58
 */
public class JarUtils {

    /*
     * description：根据jar包获取宿主项目的根路径下所有的类的全路径
     **/
    public static List<String> getClassPathByJar(Object object) {
        List<String> list = new ArrayList<>();
        try {
            List<String> resultList = new ArrayList<String>();
            resultList = getDirFiles(new File(object.getClass().getResource("/").getPath()));
            resultList = getDirFiles(new File(object.getClass().getResource("").getPath()));
            for (String classPath : resultList) {
                String s = null;
                if (OSinfo.isWindows()) {
                    String[] paths = classPath.split("classes\\\\");
                    s = paths[1].replaceAll("\\\\", ".");
                } else if (OSinfo.isLinux()) {
                    String[] paths = classPath.split("\\classes");
                    s = paths[1].replaceAll("/", ".");
                }
                if(s!=null){
                    list.add(s.split(".class")[0]);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    //通过loader加载所有类
    public static List<Class> loadClassByLoader(ClassLoader load) throws Exception{
        Enumeration<URL> urls = load.getResources("");
        //放所有类型
        List<Class> classes = new ArrayList<Class>();
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            //文件类型（其实是文件夹）
            if (url.getProtocol().equals("file")) {
                loadClassByPath(null, url.getPath(), classes, load);
            }
        }
        return classes;
    }
    //通过文件路径加载所有类 root 主要用来替换path中前缀（除包路径以外的路径）
    private static void loadClassByPath(String root, String path, List<Class> list, ClassLoader load) {
        File f = new File(path);
        if(root==null) root = f.getPath();
        //判断是否是class文件
        if (f.isFile() && f.getName().matches("^.*\\.class$")) {
            try {
                String classPath = f.getPath();
                //截取出className 将路径分割符替换为.（windows是\ linux、mac是/）
                String className = classPath.substring(root.length()+1,classPath.length()-6).replace('/','.').replace('\\','.');
                list.add(load.loadClass(className));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } else {
            File[] fs = f.listFiles();
            if (fs == null) return;
            for (File file : fs) {
                loadClassByPath(root,file.getPath(), list, load);
            }
        }
    }

    public static List<String> getDirFiles(File file) {
        List<String> resultList = new ArrayList<String>();
        if (file.isDirectory()) {
            for (File inner : file.listFiles()) {
                resultList.addAll(getDirFiles(inner));//递归部分
            }
        } else {
            if (file.toString().endsWith(".class")) {
                resultList.add(file.toString());//停止部分
            }
        }
        return resultList;
    }
}
